#include "stdafx.h"
#include "EXProgressCtrl.h"

// CEXProgressCtrl

IMPLEMENT_DYNAMIC(CEXProgressCtrl, CProgressCtrl)

CEXProgressCtrl::CEXProgressCtrl()
{
	m_nBitmapID = 0;
	m_nPic = 0;
	m_bSetBitmap = FALSE;

	m_nBkgndLeftWidth = 0;
	m_nBkgndRightWidth = 0;
	m_nBkgndTopHeight = 0;
	m_nBkgndBottomHeight = 0;

  m_nBkgndOffsetX = 0;
  m_nBkgndOffsetY = 0;

	m_bSetBkgndBitmap = FALSE;
	m_nBkgndBitmapID = 0;
}

CEXProgressCtrl::~CEXProgressCtrl()
{
}


BEGIN_MESSAGE_MAP(CEXProgressCtrl, CProgressCtrl)
	ON_WM_SIZE()
	ON_WM_WINDOWPOSCHANGING()
END_MESSAGE_MAP()



// CEXProgressCtrl message handlers

void CEXProgressCtrl::SetResSet(CEXBaseResSet* pResSet)
{
  m_pProgressResSet = (CEXProgressCtrlResSet *)pResSet;

  if(m_pProgressResSet->m_nType == PROGRESS_CTRL)
  {
    SetBkgndBitmap(m_pProgressResSet->m_arrImgId.GetAt(0), m_nBkgndOffsetX, 
                  m_nBkgndOffsetY);
    SetBitmap(m_pProgressResSet->m_arrImgId.GetAt(1), 
              m_pProgressResSet->m_nImg_DivideCnt);
  }
}

BOOL CEXProgressCtrl::SetBitmap(UINT nID, int nPics)
{
	CBitmap bmp;
	if( !bmp.LoadBitmap(nID) )
		return FALSE;

	if( !InitBgBitmap( bmp, m_bmpNormal, 0, nPics) )
		return FALSE;
	if( !InitBgBitmap( bmp, m_bmpSelect, 2, nPics) )
		return FALSE;
	if( !InitBgBitmap( bmp, m_bmpDisable, 3, nPics) )
		return FALSE;
	if( !InitBgBitmap( bmp, m_bmpFocus, 1, nPics) )
		return FALSE;

	bmp.DeleteObject();

	m_brProgress.DeleteObject();
	m_brProgress.CreatePatternBrush(&m_bmpNormal);

	m_nBitmapID = nID;
	m_nPic = nPics;
	m_bSetBitmap = TRUE;

	return TRUE;
}

BOOL CEXProgressCtrl::InitBgBitmap( CBitmap & bmpSrc, CBitmap & bmpDest, 
                                   int nIndex, int nCount )
{
	CDC * pDC = GetDC();

	CDC memDC; 
	memDC.CreateCompatibleDC(pDC);

	CDC srcDC;
	srcDC.CreateCompatibleDC(pDC);

	CBitmap* pOldBitmap1;
	pOldBitmap1 = srcDC.SelectObject(&bmpSrc);

	CRect rc;
	GetClientRect(rc);

	BITMAP bmpinfo;
	bmpSrc.GetBitmap(&bmpinfo);
	int bmpWidth = bmpinfo.bmWidth / nCount;
	int bmpHeight = bmpinfo.bmHeight;;
	int orix = bmpWidth * (nIndex < nCount ? nIndex : 0);

	bmpDest.DeleteObject();
	bmpDest.CreateCompatibleBitmap(pDC, bmpWidth, rc.Height()-m_nBkgndOffsetY*2);

	CBitmap* pOldBitmap2;
	pOldBitmap2 = memDC.SelectObject(&bmpDest);

	memDC.StretchBlt(0, 0, bmpWidth, rc.Height() - m_nBkgndOffsetY * 2, &srcDC, 
                  orix, 0, bmpWidth, bmpHeight, SRCCOPY);

	srcDC.SelectObject(pOldBitmap1);
	memDC.SelectObject(pOldBitmap2);

	ReleaseDC(pDC);
	ReleaseDC(&srcDC);
	ReleaseDC(&memDC);

	return TRUE;
}

int CEXProgressCtrl::SetPos(int nPos)
{
	int nRet = CProgressCtrl::SetPos(nPos);
	Invalidate(FALSE);
	return nRet;
}

int CEXProgressCtrl::StepIt()
{
	int nRet = CProgressCtrl::StepIt();
	Invalidate(FALSE);
	return nRet;
}

LRESULT CEXProgressCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_PAINT && m_bSetBitmap)
	{
		CPaintDC dc(this);

		CRect rcClient;
		GetWindowRect(rcClient);
		rcClient.OffsetRect(-rcClient.left, -rcClient.top);

		CDC dcMem;
		CBitmap bmpMem;

		dcMem.DeleteDC();
		dcMem.CreateCompatibleDC(&dc);

		bmpMem.DeleteObject();
		bmpMem.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());

		CBitmap * pOldBmpMem = NULL;
		pOldBmpMem = dcMem.SelectObject(&bmpMem);

		if (m_bSetBkgndBitmap)
		{
			CDC dcBkgnd;
			dcBkgnd.CreateCompatibleDC(&dc);

			CBitmap * pOldBmpBkgnd = NULL;
			pOldBmpBkgnd = dcBkgnd.SelectObject(&m_bmpBkgnd);

			dcMem.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), 
                  &dcBkgnd, 0, 0, SRCCOPY);

			dcBkgnd.SelectObject(pOldBmpBkgnd);
		}

		int nLower, nUpper;
		GetRange(nLower, nUpper);
		
		int nPos = GetPos();

		int nWidth = min(int(((rcClient.Width()-m_nBkgndOffsetX*2) / 
                      (double)(nUpper-nLower)) * nPos), rcClient.Width() -
                      m_nBkgndOffsetX*2);

		CRect rcDraw;
		rcDraw.SetRect(m_nBkgndOffsetX, m_nBkgndOffsetY, m_nBkgndOffsetX+nWidth, 
                    rcClient.bottom-m_nBkgndOffsetY);

		dcMem.FillRect(rcDraw, &m_brProgress);
	
		dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &dcMem, 0, 0, SRCCOPY);

		dcMem.SelectObject(pOldBmpMem);
		pOldBmpMem = NULL;

		return TRUE;
	}
	else if (message == WM_ERASEBKGND)
	{
		return FALSE;
	}

	return CProgressCtrl::WindowProc(message, wParam, lParam);
}

void CEXProgressCtrl::OnSize(UINT nType, int cx, int cy)
{
	CProgressCtrl::OnSize(nType, cx, cy);

	if (IsWindow(GetSafeHwnd()))
	{
		if (m_bSetBkgndBitmap)
			SetBkgndBitmap(m_nBkgndBitmapID, m_nBkgndLeftWidth, m_nBkgndRightWidth, 
                      m_nBkgndTopHeight, m_nBkgndBottomHeight, 
                      m_nBkgndOffsetX, m_nBkgndOffsetY);

		if (m_bSetBitmap)
			SetBitmap(m_nBitmapID, m_nPic);
	}
}

BOOL CEXProgressCtrl::SetBkgndBitmap(UINT nBkgndID, int nOffsetX /*= 0*/, 
                                     int nOffsetY /*= 0*/, 
                                     int nLeftWidth /*= 0*/, 
                                     int nRightWidth /*= 0*/, 
                                     int nTopHeight /*= 0*/, 
                                     int nBottomHeight /*= 0*/)
{
	CDC * pDC = GetDC();

	CDC memDC;
	memDC.CreateCompatibleDC(pDC);

	CDC srcDC;
	srcDC.CreateCompatibleDC(pDC);

	CBitmap bmpSrc;
	bmpSrc.LoadBitmap(nBkgndID);

	CBitmap* pOldBitmap1;
	pOldBitmap1 = srcDC.SelectObject(&bmpSrc);

	BITMAP bmpinfo;
	bmpSrc.GetBitmap(&bmpinfo);
	int bmpWidth = bmpinfo.bmWidth;
	int bmpHeight = bmpinfo.bmHeight;

	CRect rc;
	GetWindowRect(rc);
	rc.OffsetRect(-rc.left, -rc.top);

	m_bmpBkgnd.DeleteObject();
	m_bmpBkgnd.CreateCompatibleBitmap(pDC,rc.Width(), rc.Height());

	CBitmap* pOldBitmap2;
	pOldBitmap2 = memDC.SelectObject(&m_bmpBkgnd);

	if (!nLeftWidth && !nRightWidth && !nTopHeight && !nBottomHeight)
	{
		memDC.TransparentBlt(0, 0, rc.Width(), rc.Height(), 
                        &srcDC, 0, 0, bmpWidth, bmpHeight, RGB(255,0,255));
	}
	else
	{
		// entireimage
		memDC.TransparentBlt(nLeftWidth,
			nTopHeight,
			rc.Width()  - ( nLeftWidth + nRightWidth ) ,
			rc.Height() -  ( nTopHeight + nBottomHeight) ,
			&srcDC,
			nLeftWidth,
			nTopHeight,
			bmpWidth - ( nLeftWidth + nRightWidth ) ,
			bmpHeight - ( nTopHeight + nBottomHeight ) , RGB(255,0,255));

		// topbar,bottombar( Stretch )
		memDC.TransparentBlt(nLeftWidth,0, rc.Width() - (nLeftWidth + nRightWidth), 
                        nTopHeight,	&srcDC, nLeftWidth, 0, 
                        bmpWidth - ( nLeftWidth + nRightWidth), 
                        nTopHeight, RGB(255,0,255));

		memDC.TransparentBlt(nLeftWidth, rc.bottom - nBottomHeight, rc.Width() - 
                        (nLeftWidth + nRightWidth), nBottomHeight,	&srcDC, 
                        nLeftWidth, bmpHeight - nBottomHeight, bmpWidth - 
                        (nLeftWidth+nRightWidth),nBottomHeight,RGB(255,0,255));

		
		memDC.TransparentBlt(0, nTopHeight, nLeftWidth, rc.bottom - nTopHeight - 
                        nBottomHeight, &srcDC, 0, nTopHeight, nLeftWidth, 
                        bmpHeight-(nTopHeight + nBottomHeight), RGB(255,0,255));

		memDC.TransparentBlt(rc.right - nRightWidth , nTopHeight, nRightWidth, 
                        rc.bottom - nTopHeight - nBottomHeight, &srcDC, 
                        bmpWidth - nRightWidth, nTopHeight, nRightWidth, 
                        bmpHeight-nTopHeight-nBottomHeight , RGB(255,0,255));

		// lefttop,leftbottom,righttop,rightbottom
		if( !memDC.TransparentBlt(0, 0, nLeftWidth, nTopHeight, &srcDC, 0, 0, 
                        nLeftWidth, nTopHeight, RGB(255,0,255)) ) return FALSE;

		if( !memDC.TransparentBlt(0,rc.bottom - nBottomHeight, nLeftWidth, 
                              nBottomHeight, &srcDC, 0, bmpHeight - 
                              nBottomHeight, nLeftWidth, nBottomHeight, 
                              RGB(255,0,255)) ) 
        return FALSE;

		if(!memDC.TransparentBlt(rc.right-nRightWidth, 0 , nRightWidth, nTopHeight, 
			                      &srcDC, bmpWidth - nRightWidth, 0, nRightWidth, 
                            nTopHeight, RGB(255,0,255)) ) 
        return FALSE;

		if( !memDC.TransparentBlt(rc.right - nRightWidth,rc.bottom - nBottomHeight, 
                            nRightWidth, nBottomHeight,	&srcDC, bmpWidth - 
                            nRightWidth, bmpHeight - nBottomHeight, nRightWidth, 
                            nBottomHeight, RGB(255,0,255)) ) 
        return FALSE;
	}

	srcDC.SelectObject(pOldBitmap1);
	memDC.SelectObject(pOldBitmap2);

	ReleaseDC(pDC);
	ReleaseDC(&srcDC);
	ReleaseDC(&memDC);

	m_brNonProgress.DeleteObject();
	m_brNonProgress.CreatePatternBrush(&m_bmpBkgnd);

	m_nBkgndBitmapID = nBkgndID;
	m_nBkgndLeftWidth = nLeftWidth;
	m_nBkgndRightWidth = nRightWidth;
	m_nBkgndTopHeight = nTopHeight;
	m_nBkgndBottomHeight = nBottomHeight;
	m_nBkgndOffsetX = nOffsetX;
	m_nBkgndOffsetY = nOffsetY;
	m_bSetBkgndBitmap = TRUE;

	return TRUE;
}
